package com.tanhua.dubbo.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.LoggingEvent;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.enums.AgeRangeEnum;
import com.tanhua.common.enums.AreaEnum;
import com.tanhua.common.mapper.DashboardMapper;
import com.tanhua.common.pojo.Dashboard;
import com.tanhua.dubbo.server.pojo.UserLog;
import com.tanhua.dubbo.server.vo.DistributionVo;
import com.tanhua.dubbo.server.vo.SummaryVo;
import com.tanhua.dubbo.server.vo.UsersVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.MongoCollectionUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class DashboardService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private DashboardMapper dashboardMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    private static final Integer WEEK = 7;
    private static final Integer MONTH = 30;
    private static final Integer ONE = 1;
    private static final Long DAY = 3600 * 24 * 1000L;

    /**
     * 注册用户分布，行业top、年龄、性别、地区
     * 开始时间
     *
     * @param sd 结束时间
     * @param ed
     * @return
     */
    public DistributionVo queryAllUserInfo(String sd, String ed) {

        //先将开始和结束时间设为null
        Date startTime = null;
        Date endTime = null;
        try {
            //将时间戳转换为日期字符串使用SimpleDateFormat方法
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String sdStr = sdf.format(new Date(Long.parseLong(sd)));
            String edStr = sdf.format(new Date(Long.parseLong(ed)));

            //将日期字符串转为日期格式
            Date stime = DateUtil.parse(sdStr);
            Date etime = DateUtil.parse(edStr);

            //使用hutool工具设置开始和结束时间
            startTime = DateUtil.beginOfDay(stime);
            endTime = DateUtil.endOfDay(etime);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //创建DistributionVo页面需要的数据的实体类对象
        DistributionVo distributionVo = new DistributionVo();
        //行业分布
        List<Dashboard> industryDistribution = new ArrayList<>();
        //年龄分布
        List<Dashboard> ageDistribution = new ArrayList<>();
        //性别分布
        List<Dashboard> genderDistribution = new ArrayList<>();
        //地区分布
        List<Dashboard> localDistribution = new ArrayList<>();
        //地区合计
        List<Dashboard> localTotal = new ArrayList<>();

        //创建查询条件
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        //数据库中的created既是开始时间也是结束时间根据这个字段来查询这个时间内的所有userInfo信息
        queryWrapper.ge("created", startTime).le("created", endTime);
        //查询所有符合条件的userInfoList信息
        List<UserInfo> userInfoList = userInfoMapper.selectList(queryWrapper);
        //新建一个map集合为其后面地区分布封装数据
        Map<String, Integer> cityMap = new HashMap<>();
        //新建一个map集合为其添加数据key为地区value初始值为0
        Map<String, Integer> areaMap = new HashMap<>();
        //新建一个map集合为其后面年龄分布封装数据
        Map<String, Integer> ageMap = new HashMap<>();
        //新建一个map集合为其后面性别封装数据
        Map<String, Integer> sexMap = new HashMap<>();
        //新建一个map集合为其后面行业分布封装数据
        Map<String, Integer> industryMap = new HashMap<>();

        //地区map集合
        areaMap.put("华中地区", 0);
        areaMap.put("华北地区", 0);
        areaMap.put("华东地区", 0);
        areaMap.put("华南地区", 0);
        areaMap.put("西北地区", 0);
        areaMap.put("东北地区", 0);
        areaMap.put("西南地区", 0);
        //年龄map集合
        ageMap.put("0-17岁", 0);
        ageMap.put("18-23岁", 0);
        ageMap.put("24-30岁", 0);
        ageMap.put("31-40岁", 0);
        ageMap.put("41-50岁", 0);
        ageMap.put("50岁以上", 0);
        //性别map集合
        sexMap.put("男", 0);
        sexMap.put("女", 0);
        sexMap.put("未知", 0);

        for (UserInfo userInfo : userInfoList) {
            //遍历userInfoList集合获取所有对象的城市信息
            String city = userInfo.getCity();
            QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
            //建立查询条件
            wrapper.eq("city", city).ge("created", startTime).le("created", endTime);
            //查询城市对应人数数量
            Integer integer = userInfoMapper.selectCount(wrapper);
            //将数据封装至map集合
            cityMap.put(city, integer);

            //根据枚举类获取地区信息
            String area = AreaEnum.getAreaByProvince(city);
            //当area与map键相同时值加一得到所有地区的人数
            areaMap.put(area, areaMap.get(area) + 1);

            //年龄查询
            //查询所有符合条件的年龄
            Integer age = userInfo.getAge();
            //使用枚举判断年龄区间
            String ageArea = AgeRangeEnum.getAgeArea(age);
            //将数据存入集合中
            ageMap.put(ageArea, ageMap.get(ageArea) + 1);

            //性别查询
            SexEnum sexEnum = userInfo.getSex();
            //使用枚举判断性别再将数据封装至map集合
            sexMap.put(sexEnum.toString(), sexMap.get(sexEnum.toString()) + 1);

            //行业分布
            //查询所有城市
            String industry = userInfo.getIndustry();
            QueryWrapper<UserInfo> industryWrapper = new QueryWrapper<>();
            //建立查询条件
            industryWrapper.eq("industry", industry).ge("created", startTime).le("created", endTime);
            //查询所有行业对应人数
            Integer count = userInfoMapper.selectCount(industryWrapper);
            //封装至集合中
            industryMap.put(industry, count);
        }

        //地区分布
        List<Dashboard> localDistributionList = queryDashboard(cityMap, localDistribution);
        //地区合计
        List<Dashboard> localTotalList = queryDashboard(areaMap, localTotal);
        //年龄分布
        List<Dashboard> ageDistributionList = queryDashboard(ageMap, ageDistribution);
        //性别分布
        List<Dashboard> genderDistributionList = queryDashboard(sexMap, genderDistribution);
        //行业分布
        List<Dashboard> industryDistributionList = queryDashboard(industryMap, industryDistribution);

        //封装完所有数据人后返回前端页面
        distributionVo.setLocalDistribution(localDistributionList);
        distributionVo.setLocalTotal(localTotalList);
        distributionVo.setAgeDistribution(ageDistributionList);
        distributionVo.setGenderDistribution(genderDistributionList);
        distributionVo.setIndustryDistribution(industryDistributionList);
        return distributionVo;
    }

    /**
     * 封装方法传入map集合和list对象为其赋值
     *
     * @param map
     * @param list
     * @return
     */
    public List<Dashboard> queryDashboard(Map<String, Integer> map, List<Dashboard> list) {
        Iterator iterator = map.entrySet().iterator();
        for (int i = 0; i < map.size(); i++) {
            Dashboard dashboard = new Dashboard();
            Map.Entry entry = (Map.Entry) iterator.next();
            dashboard.setTitle(Convert.toStr(entry.getKey()));
            dashboard.setAmount(Convert.toInt(entry.getValue()));
            list.add(dashboard);
        }
        return list;
    }


    /**
     * 新增、活跃用户、次日留存率
     *
     * @param sd
     * @param ed
     * @param type
     * @return
     */
    public UsersVo queryUsersInfo(Long sd, Long ed, int type) {
        //先进行数据校验
        if (!StringUtils.equalsAny(Convert.toStr(type), "101", "102", "103")) {
            log.error("查询类型出错" + type);
            return null;
        }

        UsersVo usersVo = new UsersVo();
        //封装今年数据的集合
        List<Dashboard> list = new ArrayList<>();
        //封装去年数据的集合
        List<Dashboard> lastList = new ArrayList<>();
        //转为时间对象
        Date startTime = new Date(sd);

        Calendar sted = Calendar.getInstance();
        //将日期对象转为日历对象
        sted.setTime(startTime);
        //将一天的开始时间设为0:0
        sted.set(Calendar.HOUR, 0);
        sted.set(Calendar.MINUTE, 0);

        Calendar eted = Calendar.getInstance();
        eted.setTime(startTime);
        //将一天的结束时间设为23:59
        eted.set(Calendar.HOUR, 23);
        eted.set(Calendar.MINUTE, 59);

        //求出前端传的数据的差值判断是查七天还是一个月
        long chazhi = ed - sd;
        //转为天数
        long day = chazhi / 1000 / 60 / 60 / 24;

        //新增用户
        if (type == 101) {
            //如果是查七天
            if (day <= 7) {
                //调用方法获取今年这7天内所有符合条件的数据
                getNewUsers(8, sted, eted, list);
                //查询完今年的数据后将天数需要往前推回七天再把年数往前推一年查询去年的数据
                sted.set(Calendar.DATE, sted.get(Calendar.DATE) - 7);
                eted.set(Calendar.DATE, eted.get(Calendar.DATE) - 7);
                sted.set(Calendar.YEAR, sted.get(Calendar.YEAR) - 1);
                eted.set(Calendar.YEAR, eted.get(Calendar.YEAR) - 1);
                //调用方法获取去年这七天的所有符合条件的数据
                getNewUsers(8, sted, eted, lastList);
            } else {
                //调用方法获取今年这30天内所有符合条件的数据
                getNewUsers(31, sted, eted, list);
                //查询完今年的数据后将天数需要往前推回30天再把年数往前推一年查询去年的数据
                sted.set(Calendar.DATE, sted.get(Calendar.DATE) - 30);
                eted.set(Calendar.DATE, eted.get(Calendar.DATE) - 30);
                sted.set(Calendar.YEAR, sted.get(Calendar.YEAR) - 1);
                eted.set(Calendar.YEAR, eted.get(Calendar.YEAR) - 1);
                //调用方法获取去年这30天的所有符合条件的数据
                getNewUsers(31, sted, eted, lastList);

            }
            //type类型为102时查询活跃用户
        } else if (type == 102) {
            if (day <= 7) {
                //调用方法获取今年这七天的符合条件的数据
                getActiveCount(8, sted, eted, list);
                //查询完今年的数据后将天数需要往前推回7天再把年数往前推一年查询去年的数据
                sted.set(Calendar.DATE, sted.get(Calendar.DATE) - 7);
                eted.set(Calendar.DATE, eted.get(Calendar.DATE) - 7);
                sted.set(Calendar.YEAR, sted.get(Calendar.YEAR) - 1);
                eted.set(Calendar.YEAR, eted.get(Calendar.YEAR) - 1);
                //调用方法获取去年这7天内的符合条件的数据
                getActiveCount(8, sted, eted, lastList);
            } else {
                //调用方法获取今年这30天的符合条件的数据
                getActiveCount(31, sted, eted, list);
                //查询完今年的数据后将天数需要往前推回30天再把年数往前推一年查询去年的数据
                sted.set(Calendar.DATE, sted.get(Calendar.DATE) - 30);
                eted.set(Calendar.DATE, eted.get(Calendar.DATE) - 30);
                sted.set(Calendar.YEAR, sted.get(Calendar.YEAR) - 1);
                eted.set(Calendar.YEAR, eted.get(Calendar.YEAR) - 1);
                //调用方法获取去年这30天的符合条件的数据
                getActiveCount(31, sted, eted, lastList);
            }
            //类型为103时为查询留存率
        } else if (type == 103) {
            if (day <= 7) {
                //调用方法获取今年的这七日留存率
                getRate(8, sted, eted, list);
                //查询完今年的数据后将天数需要往前推回7天再把年数往前推一年查询去年的数据
                sted.set(Calendar.DATE, sted.get(Calendar.DATE) - 7);
                eted.set(Calendar.DATE, eted.get(Calendar.DATE) - 7);
                sted.set(Calendar.YEAR, sted.get(Calendar.YEAR) - 1);
                eted.set(Calendar.YEAR, eted.get(Calendar.YEAR) - 1);
                //调用方法获取去年的这七日留存率
                getRate(8, sted, eted, lastList);
            } else {
                //调用方法获取今年的这30日留存率
                getRate(31, sted, eted, list);
                //查询完今年的数据后将天数需要往前推回30天再把年数往前推一年查询去年的数据
                sted.set(Calendar.DATE, sted.get(Calendar.DATE) - 30);
                eted.set(Calendar.DATE, eted.get(Calendar.DATE) - 30);
                sted.set(Calendar.YEAR, sted.get(Calendar.YEAR) - 1);
                eted.set(Calendar.YEAR, eted.get(Calendar.YEAR) - 1);
                //调用方法获取去年的这30日留存率
                getRate(31, sted, eted, lastList);
            }
        }
        //存入今年数据返回页面
        usersVo.setThisYear(list);
        //存入去年数据返回页面
        usersVo.setLastYear(lastList);
        return usersVo;
    }


    /**
     * 概要信息统计
     *
     * @return
     */
    public SummaryVo querySummary() {
        SummaryVo summaryVo = new SummaryVo();

        //累计用户
        Integer count = userInfoMapper.selectCount(null);
        summaryVo.setCumulativeUsers(count);

        //过去7天活跃用户
        summaryVo.setActivePassWeek(getActiveWeekOrMonth(WEEK));

        //过去30天活跃用户
        summaryVo.setActivePassMonth(getActiveWeekOrMonth(MONTH));

        //今日新增用户
        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        //设置开始时间
        startCalendar.set(Calendar.HOUR,-12);
        startCalendar.set(Calendar.MINUTE,0);
        startCalendar.set(Calendar.SECOND,0);
        //设置结束时间
        endCalendar.set(Calendar.HOUR,11);
        endCalendar.set(Calendar.MINUTE,59);
        endCalendar.set(Calendar.SECOND,59);
        //转为日期对象
        Date startTime = startCalendar.getTime();
        Date endTime = endCalendar.getTime();
        //调用方法传入一天的开始和结束时间获得新增人数
        List<UserInfo> newUserList = getNewUserList(startTime.getTime(),endTime.getTime() );
        summaryVo.setNewUsersToday(newUserList.size());

        //今日新增用户涨跌率，单位百分数，正数为涨，负数为跌
        Calendar startCalendar2 = new GregorianCalendar();
        Calendar endCalendar2 = new GregorianCalendar();
        //设置开始时间并且要向前推一天
        startCalendar2.add(Calendar.DATE,-1);
        startCalendar2.set(Calendar.HOUR,-12);
        startCalendar2.set(Calendar.MINUTE,0);
        startCalendar2.set(Calendar.SECOND,0);

        //设置结束时间并且要向前推一天
        endCalendar2.add(Calendar.DATE,-1);
        endCalendar2.set(Calendar.HOUR,11);
        endCalendar2.set(Calendar.MINUTE,59);
        endCalendar2.set(Calendar.SECOND,59);
        //获取日期对象
        Date time2 = startCalendar2.getTime();
        Date time3 = endCalendar2.getTime();
        List<UserInfo> newUserList2 = getNewUserList(time2.getTime(), time3.getTime());
        if (newUserList.size() != 0 && newUserList2.size() != 0) {
            //如果两天增长不为0就计算涨跌率
            int rate1 = newUserList.size() - newUserList2.size();
            double rate2 = Convert.toDouble(newUserList2.size());
            Double rate = rate1 / rate2;
            summaryVo.setNewUsersTodayRate(Convert.toInt(rate * 100));
        } else {
            summaryVo.setNewUsersTodayRate(0);
        }

        //今日登录次数
        QueryWrapper<LoggingEvent> wrapper = new QueryWrapper<>();
        wrapper.ge("timestmp", System.currentTimeMillis() - DAY).le("timestmp", System.currentTimeMillis()).eq("arg1", "user");
        List<LoggingEvent> loggingEvents = dashboardMapper.selectList(wrapper);
        summaryVo.setLoginTimesToday(loggingEvents.size());

        //今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
        QueryWrapper<LoggingEvent> wrapper2 = new QueryWrapper<>();
        wrapper2.ge("timestmp", System.currentTimeMillis() - 2 * DAY).le("timestmp", System.currentTimeMillis() - DAY).eq("arg1", "user");
        List<LoggingEvent> loggingEvents2 = dashboardMapper.selectList(wrapper);
        if (loggingEvents.size() != 0 && loggingEvents2.size() != 0) {
            int loginRate = (loggingEvents.size() - loggingEvents2.size()) / (loggingEvents2.size());
            summaryVo.setLoginTimesTodayRate(loginRate);
        } else {
            summaryVo.setLoginTimesTodayRate(0);
        }

        //今日活跃用户
        //计算今日的时间区间
        Long todayStart = System.currentTimeMillis() - DAY;
        long todayEnd = System.currentTimeMillis();
        //调用方法获得该时间内活跃用户
        Integer activeUsersCount = getActiveUsersCount(todayStart, todayEnd);
        summaryVo.setActiveUsersToday(activeUsersCount);

        //昨日活跃用户
        double yesterdayCount = Double.valueOf(getActiveUsersCount(System.currentTimeMillis() - DAY * 2, System.currentTimeMillis() - DAY));
        summaryVo.setActiveUsersYesterday(Convert.toInt(yesterdayCount));

        //今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        //当两日活跃数不为空时进行涨跌率计算
        if (activeUsersCount != 0 && yesterdayCount != 0) {
            double userRate = (activeUsersCount - yesterdayCount) / yesterdayCount;
            summaryVo.setActiveUsersTodayRate(Convert.toInt(userRate));
        } else {
            //为空值直接返回0
            summaryVo.setActiveUsersTodayRate(0);
        }
        //昨日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        //先计算前天的用户活跃数
        int beforeYesterday = getActiveUsersCount(System.currentTimeMillis() - DAY * 3, System.currentTimeMillis() - DAY * 2);
        //当两日活跃数不为空时进行涨跌率计算
        if (yesterdayCount != 0 && beforeYesterday != 0) {
            double yesterdayRate = (yesterdayCount - beforeYesterday) / beforeYesterday;
            summaryVo.setActiveUsersYesterdayRate(Convert.toInt(yesterdayRate));
        } else {
            //为空值直接返回0
            summaryVo.setActiveUsersYesterdayRate(0);
        }

        //过去7天平均日使用时长，单位秒
        //先获取过去七日时间戳
        Long sd = System.currentTimeMillis() - DAY * 7;
        Long ed = System.currentTimeMillis();
        //调用方法获取这个时间段内的所有活跃用户
        List<UserLog> userLogList = getActiveUsers(sd, ed);
        long countTimeNum = 0;
        long num = 0;
        //循环遍历获取使用时长
        if (userLogList.size() != 0) {
            for (UserLog userLog : userLogList) {
                //将使用时长相加
                long countTime = userLog.getCountTime();
                countTimeNum += countTime;
                num = countTimeNum / userLogList.size();
            }
        }
        //响应前端数据
        summaryVo.setUseTimePassWeek(Convert.toInt(num));
        return summaryVo;
    }


    /**
     * 范围时间内新增用户
     *
     * @param sd 开始时间
     * @param ed 结束时间
     * @return
     */
    private List<UserInfo> getNewUserList(Long sd, Long ed) {
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.ge("created", new Date(sd)).le("created", new Date(ed));
        List<UserInfo> userInfoList = userInfoMapper.selectList(wrapper);
        return userInfoList;
    }

    /**
     * 获取累计天数内的活跃用户
     *
     * @param day
     * @return
     */
    public Integer getActiveWeekOrMonth(Integer day) {
        DateTime dateTime = new DateTime();
        long startDay = dateTime.withMillisOfDay(0).plusDays(-day).getMillis();
        long endDay = System.currentTimeMillis();
        return getActiveUsersCount(startDay, endDay);
    }

    /**
     * 获取活跃用户,在规定时间内登录过即为活跃用户
     *
     * @param sd
     * @param ed
     * @return
     */
    public Integer getActiveUsersCount(Long sd, Long ed) {
        //设置查询条件,在这个时间段内登陆过一次即为活跃用户
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("created").lte(ed), Criteria.where("created").gte(sd));
        Query query = new Query(criteria);
        List<UserLog> userLogs = mongoTemplate.findDistinct(query, "userId", "user_Log", UserLog.class);
        return userLogs.size();
    }

    /**
     * 获取范围时间内所有活跃用户
     *
     * @param sd
     * @param ed
     * @return
     */
    public List<UserLog> getActiveUsers(Long sd, Long ed) {
        //设置查询条件,在这个时间段内登陆过一次即为活跃用户
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("created").lte(ed), Criteria.where("created").gte(sd));
        Query query = new Query(criteria);
        List<UserLog> userLogs = mongoTemplate.find(query, UserLog.class);
        return userLogs;
    }

    /**
     * 查询新增用户
     *
     * @param num
     * @param sted
     * @param eted
     * @param list
     * @return
     */
    public List<Dashboard> getNewUsers(int num, Calendar sted, Calendar eted, List<Dashboard> list) {
        for (int i = 1; i <= num; i++) {
            //创建Dashboard的对象
            Dashboard dashboard = new Dashboard();
            //标题设置
            dashboard.setTitle(sted.get(Calendar.MONTH) + 1 + "月" + sted.get(Calendar.DATE) + "日");
            //创建查询条件注册时间大于开始并小于结束时间就是符合条件的数据
            QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
            wrapper.ge("created", sted.getTime()).le("created", eted.getTime());
            //查询数量
            Integer count = userInfoMapper.selectCount(wrapper);
            //给dashboard赋值
            dashboard.setAmount(count);
            //为集合添加数据
            list.add(dashboard);
            //查询完今天的后将日期往后推一天继续查下一天的
            sted.set(Calendar.DATE, sted.get(Calendar.DATE) + 1);
            eted.set(Calendar.DATE, sted.get(Calendar.DATE) + 1);
        }
        //返回数据
        return list;
    }

    /**
     * 查询活跃用户
     *
     * @param num
     * @param sted
     * @param eted
     * @param list
     * @return
     */
    private List<Dashboard> getActiveCount(int num, Calendar sted, Calendar eted, List<Dashboard> list) {
        for (int i = 1; i <= num; i++) {
            //创建Dashboard的对象
            Dashboard dashboard = new Dashboard();
            //标题设置
            dashboard.setTitle(sted.get(Calendar.MONTH) + 1 + "月" + sted.get(Calendar.DATE) + "日");
            //调用获取活跃用户方法获取这段时间内符合条件的所有数据
            Integer count = getActiveUsersCount(sted.getTime().getTime(), eted.getTime().getTime());
            dashboard.setAmount(count);
            //向集合添加数据
            list.add(dashboard);
            //查询完今天的后将日期往后推一天继续查下一天的
            sted.set(Calendar.DATE, sted.get(Calendar.DATE) + 1);
            eted.set(Calendar.DATE, sted.get(Calendar.DATE) + 1);
        }
        //返回数据
        return list;
    }

    /**
     * 获取留存率
     *
     * @param num
     * @param sted
     * @param eted
     * @param list
     * @return
     */
    public List<Dashboard> getRate(int num, Calendar sted, Calendar eted, List<Dashboard> list) {
        for (int i = 1; i <= num; i++) {
            Dashboard dashboard = new Dashboard();
            dashboard.setTitle(sted.get(Calendar.MONTH) + 1 + "月" + sted.get(Calendar.DATE) + "日");
            //获取昨天的新增用户
            List<UserInfo> newUserList = getNewUserList(sted.getTime().getTime() - 1000 * 60 * 60 * 24, eted.getTime().getTime() - 1000 * 60 * 60 * 24);
            //当昨日新增用户不为0时
            if (newUserList.size()!=0){
                //获取昨日所有新增用户的id
                List<Object> userId = CollUtil.getFieldValues(newUserList, "userId");
                //拿所有的id去查询今天的日志表判断今天是否登录了
                Query query = Query.query(Criteria.where("userId").in(userId));
                //得到今天登录了的数据
                long count = mongoTemplate.count(query, UserLog.class);
                //如果不为0时计算得出留存率
                if (count!=0){
                    double result = Double.valueOf(count) / newUserList.size();
                    dashboard.setAmount(Convert.toInt(result * 100));
                }else {
                    //为0就直接返回0
                    dashboard.setAmount(0);
                }
            }
            //添加数据
            list.add(dashboard);
            //查询完今天的后将日期往后推一天继续查下一天的
            sted.set(Calendar.DATE, sted.get(Calendar.DATE) + 1);
            eted.set(Calendar.DATE, sted.get(Calendar.DATE) + 1);
        }
        return list;
    }
}